/************************************************************************

								Heroes IV
					  Copyright 2000, The 3DO Company

	------------------------------------------------------------------
  						       combat_spell_registration.h

	$Header: /game/combat_spell_registration.h $

	$NoKeywords: $

 ************************************************************************/

#ifndef COMBAT_SPELL_REGISTRATION_H_INCLUDED
#define COMBAT_SPELL_REGISTRATION_H_INCLUDED

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

class t_battlefield;
class t_combat_spell;
enum  t_spell;

// -------------------------------------------------------------------
// object creates a spell
// -------------------------------------------------------------------
class t_spell_factory_base
{
public:
	virtual t_combat_spell* create( t_battlefield& battlefield, t_spell spell ) const = 0;
};


// -------------------------------------------------------------------
// register a combat spell
// -------------------------------------------------------------------
class t_combat_spell_registration_base
{
protected:
	void register_spell( t_spell spell, t_spell_factory_base* factory );
	void register_spells( t_spell const* spells, int count, t_spell_factory_base* factory );
};

// -------------------------------------------------------------------
// templated object which creates a spell
// -------------------------------------------------------------------
template <class type>
class t_spell_factory : public t_spell_factory_base
{
public:
	virtual t_combat_spell* create( t_battlefield& battlefield, t_spell spell ) const;
};

template <class type>
t_combat_spell* t_spell_factory<type>::create( t_battlefield& battlefield, t_spell spell ) const
{
	return new type( battlefield, spell );
}

// -------------------------------------------------------------------
// templated version of register a combat spell
// -------------------------------------------------------------------
template <class factory_type>
class t_combat_spell_template : public t_combat_spell_registration_base
{
public:
	t_combat_spell_template( t_spell spell );
	t_combat_spell_template( t_spell const* spells, int count );
protected:
	factory_type m_factory;
};

template <class factory_type>
inline t_combat_spell_template<factory_type>::t_combat_spell_template( t_spell spell )
{
	register_spell( spell, &m_factory );
}

template <class factory_type>
inline t_combat_spell_template<factory_type>::t_combat_spell_template( t_spell const* spells, 
															           int count )
{
	register_spells( spells, count, &m_factory );
}

// -------------------------------------------------------------------
// templated version of register a combat spell
// -------------------------------------------------------------------
template <class type>
class t_combat_spell_registration : public t_combat_spell_registration_base
{
public:
	t_combat_spell_registration( t_spell spell );
	t_combat_spell_registration( t_spell const* spells, int count );
protected:
	t_spell_factory<type> m_factory;
};

template <class type>
inline t_combat_spell_registration<type>::t_combat_spell_registration( t_spell spell )
{
	register_spell( spell, &m_factory );
}

template <class type>
inline t_combat_spell_registration<type>::t_combat_spell_registration(
										  t_spell const* spells, int count )
{
	register_spells( spells, count, &m_factory );
}

// -------------------------------------------------------------------
// create a combat spell handler from a spell type
// -------------------------------------------------------------------
t_combat_spell* create_combat_spell( t_battlefield& battlefield, t_spell spell );

#endif // COMBAT_SPELL_REGISTRATION_H_INCLUDED